import { Module } from '@nestjs/common';
import { ConfigModule as NestConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { CacheModule } from '../common/cache/cache.module';
import { appConfig } from './app.config';
import { validateAppConfig } from './app.schema';
import { DynamicConfigEntity } from './dynamic-config.entity';
import { DynamicConfigService } from './dynamic-config.service';
import { ConfigCenterService } from './config-center.service';
import { DynamicBeanService } from './dynamic-bean.service';
import { ConfigCenterController } from './config-center.controller';

/**
 * 配置模块 - 框架配置中心
 * 基于 NestJS 官方示例实现
 * 参考: https://docs.nestjs.cn/techniques/configuration
 *
 * 功能特性：
 * - 静态配置管理
 * - 动态配置管理
 * - 配置缓存机制
 * - 配置热重载
 * - 配置版本管理
 * - 配置推送
 * - 动态Bean管理
 */
@Module({
  imports: [
    NestConfigModule.forRoot({
      isGlobal: true,
      load: [() => appConfig],
      envFilePath: [
        '.env.local',
        '.env.development',
        '.env.production',
        '.env',
      ],
      validate: (config: Record<string, any>) => {
        // 在开发和测试环境中跳过严格验证
        const environment = process.env.NODE_ENV || 'development';
        if (environment === 'development' || environment === 'test') {
          return config;
        }
        return validateAppConfig(config);
      },
    }),
    CacheModule,
    TypeOrmModule.forFeature([DynamicConfigEntity]),
    EventEmitterModule.forRoot({
      wildcard: false,
      delimiter: '.',
      newListener: false,
      removeListener: false,
      maxListeners: 10,
      verboseMemoryLeak: false,
      ignoreErrors: false,
    }),
  ],
  controllers: [ConfigCenterController],
  providers: [
    {
      provide: 'CACHE_PROVIDER',
      useFactory: () => {
        // 简化实现，返回一个基础的缓存对象
        const cache = new Map();
        return {
          async get<T = any>(key: string): Promise<T | null> {
            const item = cache.get(key);
            if (!item) return null;
            if (item.expire && Date.now() > item.expire) {
              cache.delete(key);
              return null;
            }
            return item.value;
          },
          async set(key: string, value: any, ttl?: number): Promise<void> {
            const expire = ttl ? Date.now() + ttl * 1000 : null;
            cache.set(key, { value, expire });
          },
          async del(key: string): Promise<void> {
            cache.delete(key);
          },
          async delMany(keys: string[]): Promise<void> {
            keys.forEach((key) => cache.delete(key));
          },
          async keys(pattern?: string): Promise<string[]> {
            return Array.from(cache.keys());
          },
        };
      },
    },
    DynamicConfigService,
    ConfigCenterService,
    DynamicBeanService,
  ],
  exports: [DynamicConfigService, ConfigCenterService, DynamicBeanService],
})
export class ConfigModule {}
